package org.xqp.hrm.service.impl;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.transaction.annotation.Transactional;
import org.xqp.hrm.config.RabbitMQConfig;
import org.xqp.hrm.constants.BaseConstants;
import org.xqp.hrm.context.LoginContext;
import org.xqp.hrm.doc.CourseDoc;
import org.xqp.hrm.domain.*;
import org.xqp.hrm.dto.CourseAddParamDto;
import org.xqp.hrm.feign.client.CourseESFeignClient;
import org.xqp.hrm.mapper.CourseMapper;
import org.xqp.hrm.service.ICourseDetailService;
import org.xqp.hrm.service.ICourseMarketService;
import org.xqp.hrm.service.ICourseService;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import org.xqp.hrm.service.ICourseTypeService;
import org.xqp.hrm.to.EmailTo;
import org.xqp.hrm.to.MessageTo;
import org.xqp.hrm.to.SMSTo;
import org.xqp.hrm.util.AjaxResult;
import org.xqp.hrm.util.AssertUtil;

import javax.validation.Valid;
import java.util.Arrays;
import java.util.Date;

import static org.xqp.hrm.constants.MQConstants.*;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author whale.chen
 * @since 2021-11-26
 */
@Service
@Transactional
public class CourseServiceImpl extends ServiceImpl<CourseMapper, Course> implements ICourseService {

    @Autowired
    private ICourseMarketService courseMarketService;

    @Autowired
    private ICourseDetailService courseDetailService;

    @Autowired
    private ICourseTypeService courseTypeService;

    @Autowired
    private CourseESFeignClient courseESFeignClient;

    @Autowired
    private RabbitTemplate rabbitTemplate;


    /**
     * 保存课程
     * 1.参数基本判断，
     *   重复值判断
     * 2.保存课程
     * 3.保存营销
     * 4.保存详情
     * 5.课程分类下课程数加一
     * @param dto ：参数对象
     */
    @Override
    public void save(CourseAddParamDto dto) {

        Course courseParma = dto.getCourse();
        CourseDetail courseDetail = dto.getCourseDetail();
        CourseMarket courseMarket = dto.getCourseMarket();

        //* 1.参数基本判断，
        //*   重复值判断
        //根据名字查询课程
        Wrapper wrapper = new EntityWrapper();
        // 这相当于拼接一条sql语句  作用是将courseParma.getName()传到数据库中去和name比较看是否存在
        wrapper.eq("name", courseParma.getName());
        Course course = super.selectOne(wrapper);
        // 断言 判断course是否为null 如果是null，就直接向下运行，如果不为null就报错课程名已经存在
        AssertUtil.isNull(course,"课程名已经存在" );


        // 从Security中获取登录用户
        Login login = LoginContext.getLogin();
        //* 2.保存课程
        courseParma.setStatus(BaseConstants.Course.STATUS_OFF_LINE);
        courseParma.setUserId(1L);
        courseParma.setUserName("yhptest1");
        courseParma.setTenantId(26L);
        courseParma.setTenantName("源码时代");
        courseParma.setCommentCount(0);
        courseParma.setSaleCount(0);
        courseParma.setViewCount(0);
        super.insert(courseParma);

        //* 3.保存营销
        courseMarket.setId(courseParma.getId());
        courseMarketService.insert(courseMarket);

        //* 4.保存详情
        courseDetail.setId(courseParma.getId());
        courseDetailService.insert(courseDetail);

        //* 5.课程分类下课程数加一

        // 通过CourseTypeId外键获取到CourseType
        CourseType courseType = courseTypeService.selectById(courseParma.getCourseTypeId());

        //通过courseType获取到Path  再将这个path以，分割成数组[1037,1039,1040]
        String[] typeIdStrs = courseType.getPath().split("\\.");

        courseTypeService.addTotalCountByIds(1,typeIdStrs);
    }

    /**
     * 课程上架
     * 1.根据ID查询课程
     * 2.判断课程状态必须是：下架
     * 3.修改课程状态为：上架
     * 4.把课程保存到ES中
     *
     * @param id ：课程ID
     */
    @Override
    public void onLineCourse(Long id) {
        //* 1.根据ID查询课程
        Course course = super.selectById(id);

        //* 2.判断课程状态必须是：下架
        AssertUtil.isEquals(course.getStatus(), BaseConstants.Course.STATUS_OFF_LINE,"状态必须是下架");

        //* 3.修改课程状态为：上架
        course.setStatus(BaseConstants.Course.STATUS_ON_LINE);
        // 添加上架时间
        course.setOnlineTime(new Date());
        // 更新
        super.updateById(course);

        /**
          * 4.把课程保存到ES中
          */

        // 4.1.编写Search的Feign接口，保存课程
        CourseMarket courseMarket = courseMarketService.selectById(id);

        CourseDoc doc = new CourseDoc();
        BeanUtils.copyProperties(courseMarket, doc);
        BeanUtils.copyProperties(course, doc);
        //收费
        doc.setChargeName(courseMarket.getCharge() == 2?"收费":"免费");
        //doc.setOnlineTime(new Date());

        AjaxResult result = courseESFeignClient.save(doc);

        AssertUtil.isTrue(result.isSuccess(),"课程发布失败" );

        // 通过短信，邮箱站内信息，给用户发布课程上线消息
        publishMessage(course);
    }


    //SPEL
    @Value("${message.content.sms.course-publish}")
    public String smsContent;

    @Value("${message.content.email.course-publish}")
    public String emailContent;

    @Value("${message.content.message.course-publish}")
    public String messageContent;

    public void publishMessage(Course course){

        //发短信
        String tempSmsContent = String.format(smsContent,course.getName() );

        rabbitTemplate.convertAndSend(NAME_EXCHANGE_TOPIC,//交换机名字
                "course.sms" ,//路由键
                new SMSTo(Arrays.asList("18233333333","18233333333") ,tempSmsContent));

        //发邮件
        String tempEmailContent = String.format(emailContent,course.getName() );

        rabbitTemplate.convertAndSend(NAME_EXCHANGE_TOPIC,//交换机名字
                "course.email" ,//路由键
                new EmailTo(Arrays.asList("182333@qq.com","182332@qq.com"),"有课程发布啦" ,tempEmailContent));

        //发邮件
        String tempMessageContent = String.format(messageContent,course.getName() );

        rabbitTemplate.convertAndSend(NAME_EXCHANGE_TOPIC,//交换机名字
                "course.message" ,//路由键
                new MessageTo(Arrays.asList(1L,2L),"有课程发布啦" ,tempMessageContent));
    }


    @Override
    public void offLineCourse(Long id) {
        //* 1.根据ID查询课程
        Course course = super.selectById(id);

        //* 2.判断课程状态必须是：上架
        AssertUtil.isEquals(course.getStatus(), BaseConstants.Course.STATUS_ON_LINE,"状态必须是上架");

        //* 3.修改课程状态为：下架
        course.setStatus(BaseConstants.Course.STATUS_OFF_LINE);

        // 添加下架时间
        course.setOfflineTime(new Date());

        // 更新
        super.updateById(course);

    }
}

